using System;
using System.Collections.Generic;

namespace Lizk.SimpleHUD
{
    public class HUDVideo : HUDImage
    {
        private bool isDVD, attemptRestart;
        private PlayerState playerState = PlayerState.NotLoaded;
        private int title;
        private int chapter;
        private MenuMode menuState = MenuMode.No;
        private int audioTrack;
        private int subtitle;
        private int angle;
        private bool error = false, stopSent = false;
        private bool enableSubtitles = false;
       

        public bool EnableSubtitles
        {
            get { return enableSubtitles; }
            set { enableSubtitles = value; }
        }




        public bool Error
        {
            get { return error; }
            set { error = value; }
        }

        private string errorMessage = "";

        public string ErrorMessage
        {
            get { return errorMessage; }
            set { errorMessage = value; }
        }




        private Queue<KeyValuePair<VideoCommands, object[]>> pendingCommands = new Queue<KeyValuePair<VideoCommands, object[]>>();

        private TimeSpan titleDuration = TimeSpan.MinValue;
        private TimeSpan position = TimeSpan.MinValue;
        private Dictionary<int, string> audioTracks = new Dictionary<int, string>();
        private Dictionary<int, string> subtitles = new Dictionary<int, string>();
        private int angleCount = 1;
        private int titleCount = 0;
        private int chapterCount = 0;

        public bool IsDVD { get { return isDVD; } }
        public bool AttemptRestart { get { return attemptRestart; } set { attemptRestart = value; } }
        public int Chapter { get { return chapter; } set { chapter = value; } }
        public int Title { get { return title; } set { title = value; } }
        public int Angle { get { return angle; } set { angle = value; } }
        public int ChapterCount { get { return chapterCount; } set { chapterCount = value; } }
        public int TitleCount { get { return titleCount; } set { titleCount = value; } }
        public int AngleCount { get { return angleCount; } set { angleCount = value; } }
        public int Subtitle { get { return subtitle; } set { 
            subtitle = value; 
        } }
        public int AudioTrack { get { return audioTrack; } set { audioTrack = value; } }

        public TimeSpan TitleDuration { get { return titleDuration; } set { titleDuration = value; } }
        public TimeSpan Position { get { return position; } set { position = value; } }
        public Dictionary<int, string> AudioTracks { get { return audioTracks; } }
        public Dictionary<int, string> Subtitles { get { return subtitles; } }
        public PlayerState State { get { return playerState; } set { playerState = value; } }
        public Queue<KeyValuePair<VideoCommands, object[]>> PendingCommands { get { return pendingCommands; } }
        public MenuMode MenuState { get { return menuState; } set { menuState = value; } }


        public HUDVideo(string path, bool isDVD) : base(path)
        {
            this.isDVD = isDVD;
        }

        private void EnqueueCommand(VideoCommands command, params object[] o)
        {
            if (error && command != VideoCommands.Stop)
                return;
            pendingCommands.Enqueue(new KeyValuePair<VideoCommands, object[]>(command, o));
        }

        public void Play()
        {
            EnqueueCommand(VideoCommands.Play, null);
        }

        public void Pause()
        {
            EnqueueCommand(VideoCommands.Pause, null);
        }

        public void Stop()
        {
            EnqueueCommand(VideoCommands.Stop, null);
        }

        public void Seek(TimeSpan ts, bool absolute)
        {
            EnqueueCommand(VideoCommands.Seek, new object[] {ts, absolute});
        }

        public void RootMenu()
        {
            EnqueueCommand(VideoCommands.RootMenu, null);
        }

        public void TitleMenu()
        {
            EnqueueCommand(VideoCommands.TitleMenu, null);
        }

        public void MenuMoveUp()
        {
            EnqueueCommand(VideoCommands.MenuUp, null);
        }

        public void MenuMoveDown()
        {
            EnqueueCommand(VideoCommands.MenuDown, null);
        }

        public void MenuMoveLeft()
        {
            EnqueueCommand(VideoCommands.MenuLeft, null);
        }

        public void MenuMoveRight()
        {
            EnqueueCommand(VideoCommands.MenuRight, null);
        }

        public void MenuSelect()
        {
            EnqueueCommand(VideoCommands.MenuSelect, null);
        }

        public void ChangeSubtitle(int id)
        {
            EnqueueCommand(VideoCommands.ChangeSubtitle, new object[] { id });
        }

        public void ChangeAudioTrack(int id)
        {
            EnqueueCommand(VideoCommands.ChangeAudioTrack, new object[] { id });
        }

        public void NextChapter()
        {
            EnqueueCommand(VideoCommands.SetChapter, new object[] {chapter + 1});
        }

        public void PreviousChapter()
        {
            EnqueueCommand(VideoCommands.SetChapter, new object[] { chapter - 1 });
        }


        public override void Update(TimeSpan ts)
        {
            if (Error && !stopSent)
            {
                EnqueueCommand(VideoCommands.Stop, null);
                stopSent = true;
            }
            base.Update(ts);
        }

        public void ChangeAngle(int angle)
        {
            EnqueueCommand(VideoCommands.ChangeAngle, angle);
        }
        public enum VideoCommands
        {
            Play,
            Pause,
            Stop,
            Seek,
            ChangeSubtitle,
            ChangeAudioTrack,
            ChangeAngle,
            RootMenu,
            TitleMenu,
            SetTitle,
            SetChapter,
            MenuUp,
            MenuDown,
            MenuLeft,
            MenuRight,
            MenuSelect,
            MenuMouseHover
        }

        public enum PlayerState
        {
            NotLoaded,
            Stopped,
            Playing,
            Paused
        }

        public enum MenuMode
        {
            No,
            Menu,
            Still
        }

    }
}